package com.cipe.cmrs.converter;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterRegistry;

import com.cipe.cmrs.bean.PaymentRequestBean;
import com.cipe.cmrs.bean.PaymentRequestLineItemBean;
import com.cipe.cmrs.helper.PaymentHelper;
import com.cipe.cmrs.model.AccountCode;
import com.cipe.cmrs.model.Cipeproject;
import com.cipe.cmrs.model.Payee;
import com.cipe.cmrs.model.Paymentrequest;
import com.cipe.cmrs.model.Paymentrequestlineitem;
import com.cipe.cmrs.model.Paymenttype;
import com.cipe.cmrs.model.User;
import com.cipe.cmrs.service.PaymentrequestService;
import com.cipe.cmrs.service.PaymentrequestlineitemService;

public class PaymentRequestBeanToPaymentRequest implements Converter<PaymentRequestBean, Paymentrequest> {

    private ConverterRegistry converterRegistry;
    private PaymentrequestService paymentrequestService;
    private PaymentrequestlineitemService paymentrequestlineitemService;
    private PaymentHelper paymentHelper;

    /**
     * @param converterRegistry
     *            the converterRegistry to set
     */
    public void setConverterRegistry(ConverterRegistry converterRegistry) {
        this.converterRegistry = converterRegistry;
    }

    public void setPaymentrequestService(PaymentrequestService paymentrequestService) {
        this.paymentrequestService = paymentrequestService;
    }

    public void setPaymentrequestlineitemService(PaymentrequestlineitemService paymentrequestlineitemService) {
        this.paymentrequestlineitemService = paymentrequestlineitemService;
    }

    public void setPaymentHelper(PaymentHelper paymentHelper) {
        this.paymentHelper = paymentHelper;
    }

    public void init() {
        converterRegistry.addConverter(this);
    }

    public Paymentrequest convert(PaymentRequestBean bean) {
        Paymentrequest request = null;
        if (bean != null) {
            if (bean.getId() != null && bean.getId() > 0) {
                request = paymentrequestService.findById(bean.getId());
                request.setUpdatedBy(bean.getUser());
                request.setUpdationDate(new Date());
            } else {
                request = new Paymentrequest();
                request.setCreatedBy(bean.getUser());
                request.setCreationDate(new Date());
            }

            if (bean.getPaymentTypeId() != null && bean.getPaymentTypeId() > 0) {
                Paymenttype type = new Paymenttype();
                type.setId(bean.getPaymentTypeId());
                request.setPaymenttype(type);
            }

            request.setPaymentIdentifiedInformation(bean.getPaymentIdentifiedInformation());
            request.setReceivedFromAccountingDate(bean.getReceivedFromAccountingDate());
            request.setPaymentmethod(bean.getPaymentMethod());

            if (bean.getPayeeId() != null && bean.getPayeeId() > 0) {
                Payee payee = new Payee();
                payee.setId(bean.getPayeeId());
                request.setPayee(payee);
            }

            request.setPurposeOfExpenditure(bean.getPurposeOfExpenditure());
            request.setSpecialInstructions(bean.getSpecialInstructions());
            request.setInvoiceRequestDate(bean.getInvoiceRequestDate());
            request.setInvoicenumber(bean.getInvoicenumber());
            request.setDateToFinanace(bean.getDateToFinanace());
            request.setStatusCode(bean.getStatusCode());
            request.setAmount(bean.getAmount() != null ? bean.getAmount() : BigDecimal.ZERO);
            request.setCurrentlyresponsible(bean.getCurrentlyresponsible());
            request.setDateforwardedforsignature(bean.getDateforwardedforsignature());
            request.setDatesubmittedforpayment(bean.getDatesubmittedforpayment());
            request.setDatepaid(bean.getDatePaid());
            request.setDaterejected(bean.getDateRejected());
            request.setComments(bean.getComments());
            request.setReasonrejected(bean.getReasonrejected());
            request.setPaymentConfirmationNumber(bean.getPaymentConfirmationNumber());
            savePaymentLineItems(request, bean, bean.getUser());
        }
        return request;
    }

    private void savePaymentLineItems(Paymentrequest dbPaymentrequest, PaymentRequestBean paymentRequestBean, User user) {
        Map<Integer, Paymentrequestlineitem> map = new HashMap<Integer, Paymentrequestlineitem>();

        List<Paymentrequestlineitem> list = dbPaymentrequest.getPaymentrequestlineitems();
        if (list == null) {
            list = new ArrayList<Paymentrequestlineitem>();
            dbPaymentrequest.setPaymentrequestlineitems(list);
        } else {
            for (Paymentrequestlineitem item : list) {
                map.put(item.getId(), item);
            }
        }

        int counter = 1;
        for (PaymentRequestLineItemBean bean : paymentRequestBean.getLineItemBeans()) {
            if (paymentHelper.hasData(bean)) {
                Paymentrequestlineitem item = map.get(bean.getId());
                if (item == null) {
                    item = new Paymentrequestlineitem();
                    item.setCreatedBy(user);
                    item.setCreationDate(new Date());
                    list.add(item);
                } else {
                    item.setUpdatedBy(user);
                    item.setUpdationDate(new Date());
                    map.remove(bean.getId());
                }
                item.setLineitemnumber(counter++);

                item.setPaymentrequest(dbPaymentrequest);

                if (bean.getAccountCodeId() != null) {
                    AccountCode accountCode = new AccountCode();
                    accountCode.setId(bean.getAccountCodeId());
                    item.setAccountCode(accountCode);
                } else {
                    item.setAccountCode(null);
                }
                if (bean.getCipeProjectId() != null) {
                    Cipeproject cipeProject = new Cipeproject();
                    cipeProject.setId(bean.getCipeProjectId());
                    item.setCipeproject(cipeProject);
                } else {
                    item.setCipeproject(null);
                }
                item.setPaymentrequestamount(bean.getAmount());
            }
        }

        for (Paymentrequestlineitem item : map.values()) {
            list.remove(item);
        }

        paymentrequestlineitemService.deleteAll(map.values());
    }

}
